﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
using System.Media;
using System.Net;
using System.Threading;
using System.Xml.Serialization;

namespace VisaValeCheck
{
    public sealed class Visa
    {        
        #region Eventos
        public event EventHandler TudoBeleza;
        public event EventHandler ErroAoAtualizar;
        public event EventHandler NovoDeposito;
        public event EventHandler NovaCompra;
        public event EventHandler DataDoCreditoDefinida;
        public event EventHandler Carregando;        
        #endregion

        public VisaSaldo Saldo { get; private set; }

        private const string _c_urlConsulta = "http://www.cbss.com.br/inst/convivencia/SaldoExtrato.jsp?numeroCartao={0}&periodoSelecionado=4";

        private CookieContainer _cookieSession = new CookieContainer();
        private System.Windows.Threading.Dispatcher _dispatcher;
        private Thread _th = null;
                
        public Visa()
        {
            _dispatcher = System.Windows.Threading.Dispatcher.CurrentDispatcher;            
            CartaoManipulation.CarregarCartoes();
            NumeroCartao cartao = CartaoManipulation.UltimoCartaoSelecionado();
            /*if (cartao != null)
                this.Consulta(cartao);*/
        }
        
        private bool CartaoValido(string paginaSaldo)
        {
            return !Regex.Match(paginaSaldo, "Cartão inválido", RegexOptions.Singleline | RegexOptions.IgnoreCase).Success;
        }
                
        public void Consulta(NumeroCartao numeroCartao)
        {            
            Saldo = SaldosSerialization.Carregar(numeroCartao);
            this.ChamaEvento(Carregando);
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(string.Format(_c_urlConsulta, numeroCartao.Numero));
            req.Headers[HttpRequestHeader.AcceptCharset] = "iso-8859-1";
            req.CookieContainer = _cookieSession;
            req.Proxy.Credentials = System.Net.CredentialCache.DefaultCredentials;
            using (HttpWebResponse resp = (HttpWebResponse)req.GetResponse())
            {
                using (Stream s = resp.GetResponseStream())
                {
                    using (StreamReader sReader = new StreamReader(s, Encoding.GetEncoding("iso-8859-1")))
                    {
                        string paginaSaldo = System.Web.HttpUtility.HtmlDecode(sReader.ReadToEnd());
                        if (!this.CartaoValido(paginaSaldo))
                            throw new Exception("Cartão inválido.");
                        lock (this)
                        {
                            VisaSaldo sldNovo = new VisaSaldo(paginaSaldo, numeroCartao);
                            if (Saldo == null)
                            {
                                Saldo = sldNovo;
                                SaldosSerialization.Salvar(sldNovo);
                                CartaoManipulation.CarregarCartoes();
                            }
                            if (Saldo.AtualizarValores(sldNovo))
                                this.ChamaEvento(DataDoCreditoDefinida);
                            if (Saldo.AdicionarCompras(sldNovo))
                                this.ChamaEvento(NovaCompra);
                            if (Saldo.AdicionarCreditos(sldNovo))
                                this.ChamaEvento(NovoDeposito);
                            SaldosSerialization.Salvar();
                        }
#if DEBUG
                        using (FileStream f = File.Open("paginas.html", FileMode.Append))
                        {
                            byte[] b = Encoding.UTF8.GetBytes("<hr />" + paginaSaldo);
                            f.Write(b, 0, b.Length);
                        }
#endif
                    }
                }
            }
            this.ChamaEvento(TudoBeleza);            
        }

        public void Sair()
        {
            if (_th != null)
            {
                _th.Abort();
                _th.Join();
            }
        }

        private void ChamaEvento(EventHandler evento)
        {
            if (evento != null)
            {               
                evento(this, new EventArgs());
            }
        }
    }
}
